package com.kkelectronics.w2b.devplugin.codegenerator.model;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.Javadoc;
import org.eclipse.jdt.core.dom.ParameterizedType;
import org.eclipse.jdt.core.dom.TagElement;
import org.eclipse.jdt.core.dom.TextElement;

import com.kkelectronics.w2b.beangen.service.FileFormattingException;
import com.kkelectronics.w2b.devplugin.codegenerator.util.ASTProvider;

@SuppressWarnings("unchecked")
public class BeanParser {

	private static final AST ast = ASTProvider.get();

	public String getClassComment(final File f) {
		String comment = "";

		BufferedReader br = null;
		try {
			br = new BufferedReader(new FileReader(f));
			String str = "";
			if (br != null) {
				try {
					while ((str = br.readLine()) != null) {
						str = str.trim();
						if (str.contains("<summary>")) {
							while (!(str = br.readLine()).contains("</summary>")) {
								comment += str.replace("///", "").trim();
								comment += " ";
							}
							break;
						}
					}
				} catch (final IOException e) {
					// TODO Auto-generated catch block
					// e.printStackTrace();
				}
			}

			br.close();

		} catch (final IOException e2) {
			System.out.println("FileNotFoundException - Caught " + f.getPath().toString());
		}
		return comment.trim();
	}

	public List<Field> parseFileForFields(final File f) throws FileFormattingException {
		final List<Field> res = new LinkedList<Field>();
		Field field = null;

		BufferedReader br = null;
		try {
			br = new BufferedReader(new FileReader(f));
			String str = "";
			String comment = "";
			String[] split;
			if (br != null) {
				while ((str = br.readLine()) != null) {
					str = str.trim();
					if ((!str.startsWith("//")) || str.startsWith("///")) {
						if (!str.contains("public class")) {
							if (str.contains("<summary>")) {
								while (!(str = br.readLine()).contains("</summary>")) {
									comment += str.replace("///", "").trim();
									comment += " ";
								}
							}
							if (str.contains("public")) {
								split = str.replaceAll("( \\{ get; set; \\}|public )", "").split(" ");
								field = new Field();
								field.setName(ast.newSimpleName(split[1]));

								field.setJavadoc(createJavaDoc(comment, ast));
								extractTypes(field, split);
								
								res.add(field);
								comment = "";
							}
						}
					}
				}
			}

			br.close();

		} catch (final IOException ex) {
			ex.printStackTrace();
		}
		return res;
	}
	
	private Javadoc createJavaDoc(final String comment, final AST ast) {
		final Javadoc jdoc = ast.newJavadoc();
		final TextElement newTextElement = ast.newTextElement();
		newTextElement.setText(comment.isEmpty() ? "TODO gen: comment is missing on park." : comment);
		final TagElement tag = ast.newTagElement();
		tag.fragments().add(newTextElement);
		jdoc.tags().add(tag);
		return jdoc;
	}

	private void extractTypes(final Field field, final String[] split) {
		final Class<?> type = getSimpleType(split[0]);
		if (type != null) {
			field.setType(ast.newSimpleType(ast.newSimpleName(type.getSimpleName())));
		} else if (split[0].contains(List.class.getSimpleName())) {
			final ParameterizedType pType = ast.newParameterizedType(ast.newSimpleType(ast.newSimpleName(List.class.getSimpleName())));
			final String[] parameterTypes = split[0].substring(split[0].indexOf("<") + 1, split[0].indexOf(">")).split(",");
			for (int i = 0; i < parameterTypes.length; i++) {
				String parameterType = parameterTypes[i];
				pType.typeArguments().add(ast.newSimpleType(ast.newSimpleName(parameterType)));
				field.addImportType(ast.newName("com.kk_electronic.w2b.legacy.datajs.interfaces." + parameterType));
			}
			field.setType(pType);
			field.addImportType(ast.newName(List.class.getName()));
		} else {
			field.setType(ast.newSimpleType(ast.newName(split[0])));
			field.addImportType(ast.newName("com.kk_electronic.w2b.legacy.datajs.interfaces." + split[0]));
		}
	}

	private Class<?> getSimpleType(final String string) {
		if ("string".equals(string)) {
			return String.class;
		} else if ("Guid".equals(string)) {
			return String.class;
		} else if ("bool".equals(string)) {
			return Boolean.class;
		} else if ("int".equals(string)) {
			return Integer.class;
		} else if ("double".equals(string)) {
			return Double.class;
		} else {
			return null;

		}
	}

	private String getListType(final String string) {
		return string.replace("List", "JsArray").substring(0, string.length() - 1) + "JS>";
	}
}
